﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace LambdaToSql.Interface
{
    /// <summary>
    /// 查询接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IQueryable<T>
    {
        /// <summary>
        /// 数据库上下文对象
        /// </summary>
        LambdaToSql.EntityModel.DbContext Context { get; set; }

        #region Any

        /// <summary>
        /// 判断满足条件的数据是否存在
        /// </summary>
        /// <returns></returns>
        bool Any();

        /// <summary>
        /// 判断满足条件的数据是否存在
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        bool Any(Expression<Func<T, bool>> expression);

        #endregion

        #region Select

        /// <summary>
        /// Select字段
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        IQueryable<T> Select(Expression<Func<T, object>> expression);

        #endregion

        #region Where

        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        IQueryable<T> Where(Expression<Func<T, bool>> expression);

        #endregion

        #region Skip Take

        /// <summary>
        /// 跳转到N页
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        IQueryable<T> Skip(int index);

        /// <summary>
        /// 取前N条
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        IQueryable<T> Take(int num);

        #endregion

        #region GroupBy OrderBy OrderByDescending

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        IQueryable<T> GroupBy(Expression<Func<T, object>> expression);

        /// <summary>
        /// 正序
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        IQueryable<T> OrderBy<T1>(Expression<Func<T, T1>> expression);

        /// <summary>
        /// 倒序
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        IQueryable<T> OrderByDescending<T1>(Expression<Func<T, T1>> expression);

        /// <summary>
        /// 倒序
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        IQueryable<T> OrderByDescending(string name);

        /// <summary>
        /// 正序
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        IQueryable<T> OrderBy(string name);



        #endregion

        #region Avg Max Min Sum Count

        /// <summary>
        /// 平均值
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        Double Avg(Expression<Func<T, object>> expression);

        /// <summary>
        /// 最大值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        TResult Max<TResult>(Expression<Func<T, TResult>> expression);

        /// <summary>
        /// 最小值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        TResult Min<TResult>(Expression<Func<T, TResult>> expression);

        /// <summary>
        /// 求和
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        Decimal Sum<TResult>(Expression<Func<T, TResult>> expression);

        /// <summary>
        /// 总数
        /// </summary>
        /// <returns></returns>
        int Count();
        #endregion

        #region First FirstOrDefault

        ///// <summary>
        ///// 查找一条实体 Guid主键类型
        ///// </summary>
        ///// <param name="guid"></param>
        ///// <returns></returns>
        //T Find(Guid guid);

        ///// <summary>
        ///// 查找一条实体 int主键类型
        ///// </summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //T Find(int id);

        /// <summary>
        /// 查找一条实体  
        /// </summary>
        /// <param name="KeyValue">主键值</param>
        /// <returns></returns>
        T Find(object KeyValue);

        /// <summary>
        /// 获取第一条
        /// </summary>
        /// <returns></returns>
        T First();

        /// <summary>
        /// 获取默认地一条
        /// </summary>
        /// <returns></returns>
        T FirstOrDefault();

        #endregion

        #region Pages

        /// <summary>
        /// 分页 默认第一页 15条
        /// </summary>
        /// <param name="total">总数</param>
        /// <returns></returns>
        IList<T> ToPageList(ref int total);

        ///// <summary>
        ///// 分页
        ///// </summary>
        ///// <param name="pageIndex">当前页码</param>
        ///// <param name="pageSize">每页数量</param>
        ///// <returns></returns>
        //IList<T> ToPageList(int pageIndex, int pageSize);

        ///// <summary>
        ///// 分页
        ///// </summary>
        ///// <param name="pageIndex">当前页码</param>
        ///// <param name="pageSize">每页数量</param>
        ///// <param name="total">总数</param>
        ///// <returns></returns>
        //IList<T> ToPageList(int pageIndex, int pageSize, ref int total);

        ///// <summary>
        ///// 分页 不建议使用
        ///// </summary>
        ///// <param name="pageIndex">当前页码</param>
        ///// <param name="pageSize">每页数量</param>
        ///// <param name="sort">排序列 字段名称</param>
        ///// <param name="order">排序类型 asc desc</param>
        ///// <param name="total">总数</param>
        ///// <returns></returns>
        //IList<T> ToPageList(int pageIndex, int pageSize, string sort, string order, ref int total);

        #endregion

        #region Join

        /// <summary>
        /// 链接查询
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        IQueryable<T> InnerJoin<T1>(Expression<Func<T1, object>> expression);


        #endregion

        #region ToList

        /// <summary>
        /// 提交数据库,返回IList集合
        /// </summary>
        /// <returns></returns>
        IList<T> ToList();

        /// <summary>
        /// 提交数据库,返回IList集合
        /// </summary>
        /// <returns></returns>
        LambdaToSql.EntityModel.Result<IList<T>> ToList(bool debug);

        #endregion
    }
}
